package com.lap.auth.adapter.security.token;

import com.lap.auth.adapter.config.JwtProperties;
import com.lap.auth.domain.shared.ports.JwtService;
import com.lap.auth.domain.shared.exception.ExpiredException;
import com.lap.framework.tools.Uid;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import javax.crypto.SecretKey;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class JwtServiceImpl implements JwtService {

  public static final String USER_ID = "id";
  private final JwtProperties jwtProperties;

  @Override
  public String generateToken(Integer userId) {
    int tokenTtlHours = jwtProperties.getExpiry().getTokenTtlHours();
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.HOUR, tokenTtlHours);

    return Jwts.builder()
        .id(Uid.getId())
        .issuer(jwtProperties.getIssuer()) // 签发人
        .claims(Map.of(USER_ID, userId))
        .issuedAt(new Date()) // 签发时间
        .expiration(calendar.getTime()) // 过期时间
        .signWith(getSignInKey())
        .compact();
  }

  @Override
  public Integer validateJwt(String token) {
    try {
      Claims claims =
          Jwts.parser().verifyWith(getSignInKey()).build().parseSignedClaims(token).getPayload();
      return claims.get(USER_ID, Integer.class);
    } catch (ExpiredJwtException e) {
      throw new ExpiredException();
    }
  }

  private SecretKey getSignInKey() {
    byte[] keyBytes = Decoders.BASE64.decode(jwtProperties.getSecretKey());
    return Keys.hmacShaKeyFor(keyBytes);
  }
}
